package com.wolf.etl.vo;

import com.wolf.etl.model.*;
import com.wolf.util.StringUtils;
import org.apache.commons.collections.CollectionUtils;

import java.util.*;

/**
 * @author sdyang
 * @date 2019/10/21 21:01
 **/
public class BuildSqlParam {

    private EtlTableModel srcTable;

    private List<EtlTableOrderbyModel> orderbys;

    private List<EtlTableFilterModel> filters;

    private Integer offset;

    private Integer fetch_max_count;

    private Map<Long, String> srcFields;

    private List<EtlTableRelModel> rels;

    private Map<Long, EtlTableModel> relMap = new HashMap<Long, EtlTableModel>();

    protected Map<Long, String> aliasMap = new HashMap<Long, String>();

    private Set<String> aliasSet = new HashSet<String>();

    private List<EtlTransformDefineModel> transformDefineModelList;

    private Map<Long,String> transformAliasMap = new HashMap<>();

    private List<EtlTransformRuleModel> transformRules;

    private Map<Long, List<EtlTransformRuleModel>> checkRuleMap = new HashMap<>();

    private Map<Long, List<EtlTransformRuleModel>> convertRuleMap = new HashMap<>();

    private Map<Long, EtlTransformRuleTypeModel> ruleTypeMap = new HashMap<>();

    private List<EtlTableRelRuleModel> tableRelRules;

    private Map<Long, List<EtlTableRelRuleModel>> masterTableRelRuleMap = new HashMap<>();

    private Map<Long, List<EtlTableRelRuleModel>> slaveTableRelRuleMap = new HashMap<>();

    public List<EtlTransformDefineModel> getTransformDefineModelList() {
        return transformDefineModelList;
    }

    public void setTransformDefineModelList(List<EtlTransformDefineModel> transformDefineModelList) {
        this.transformDefineModelList = transformDefineModelList;
    }

    public void init() {
        initAlias();
        initTransRuleMap();
        initTableRelRuleMap();
        initTransformAliasMap();
    }

    private void initTransformAliasMap(){
        for(EtlTransformDefineModel vo:transformDefineModelList){
            transformAliasMap.put(vo.getId(),aliasMap.get(vo.getSrc_table_id()));
        }
    }

    private void initTableRelRuleMap() {
        if (CollectionUtils.isEmpty(tableRelRules)) {
            return;
        }
        for (EtlTableRelRuleModel rule : tableRelRules) {

            if (rule.getRule_scope().equalsIgnoreCase("MASTER")) {
                if (masterTableRelRuleMap.containsKey(rule.getTable_rel_id())) {
                    masterTableRelRuleMap.get(rule.getTable_rel_id()).add(rule);
                } else {
                    List<EtlTableRelRuleModel> rs = new ArrayList<>();
                    rs.add(rule);
                    masterTableRelRuleMap.put(rule.getTable_rel_id(), rs);
                }

            } else {
                if (slaveTableRelRuleMap.containsKey(rule.getTable_rel_id())) {
                    slaveTableRelRuleMap.get(rule.getTable_rel_id()).add(rule);
                } else {
                    List<EtlTableRelRuleModel> rs = new ArrayList<>();
                    rs.add(rule);
                    slaveTableRelRuleMap.put(rule.getTable_rel_id(), rs);
                }
            }

        }
    }

    private void initTransRuleMap() {
        if (CollectionUtils.isEmpty(transformRules)) {
            return;
        }
        for (EtlTransformRuleModel rule : transformRules) {
            boolean isCheckRule = ruleTypeMap.get(rule.getType_id()).getIs_check();
            if (isCheckRule) {
                if (checkRuleMap.containsKey(rule.getTrans_def_id())) {
                    checkRuleMap.get(rule.getTrans_def_id()).add(rule);
                } else {
                    List<EtlTransformRuleModel> rs = new ArrayList<>();
                    rs.add(rule);
                    checkRuleMap.put(rule.getTrans_def_id(), rs);
                }
            } else {
                if (convertRuleMap.containsKey(rule.getTrans_def_id())) {
                    convertRuleMap.get(rule.getTrans_def_id()).add(rule);
                } else {
                    List<EtlTransformRuleModel> rs = new ArrayList<>();
                    rs.add(rule);
                    convertRuleMap.put(rule.getTrans_def_id(), rs);
                }
            }
        }
    }


    private void initAlias() {
        for (Map.Entry<Long, EtlTableModel> entry : relMap.entrySet()) {
            aliasMap.put(entry.getKey(), getAlias(entry.getValue()));
            aliasSet.add(getAlias(entry.getValue()));
        }
    }

    private String getAlias(EtlTableModel table) {
        if (table == null) {
            return null;
        }

        if (StringUtils.isNotEmpty(table.getAlias()) && !aliasSet.contains(table.getAlias())) {
            return table.getAlias();
        }

        String alias = StringUtils.camel(table.getName());
        if (!aliasSet.contains(alias)) {
            return alias;
        }

        // 防止重复 别名01
        alias = String.format("%s01", alias);
        if (!aliasSet.contains(alias)) {
            return alias;
        }

        // 防止重复 别名02
        alias = String.format("%s02", alias);
        if (!aliasSet.contains(alias)) {
            return alias;
        }

        return null;
    }

    public Map<Long, String> getAliasMap() {
        return aliasMap;
    }

    public void setAliasMap(Map<Long, String> aliasMap) {
        this.aliasMap = aliasMap;
    }

    public Map<Long, EtlTableModel> getRelMap() {
        return relMap;
    }

    public void setRelMap(Map<Long, EtlTableModel> relMap) {
        this.relMap = relMap;
    }

    public List<EtlTableRelModel> getRels() {
        return rels;
    }

    public void setRels(List<EtlTableRelModel> rels) {
        this.rels = rels;
    }

    public EtlTableModel getSrcTable() {
        return srcTable;
    }

    public void setSrcTable(EtlTableModel srcTable) {
        this.srcTable = srcTable;
    }

    public Map<Long, String> getSrcFields() {
        return srcFields;
    }

    public void setSrcFields(Map<Long, String> srcFields) {
        this.srcFields = srcFields;
    }

    public Set<String> getAliasSet() {
        return aliasSet;
    }

    public void setAliasSet(Set<String> aliasSet) {
        this.aliasSet = aliasSet;
    }

    public List<EtlTableOrderbyModel> getOrderbys() {
        return orderbys;
    }

    public void setOrderbys(List<EtlTableOrderbyModel> orderbys) {
        this.orderbys = orderbys;
    }

    public List<EtlTableFilterModel> getFilters() {
        return filters;
    }

    public void setFilters(List<EtlTableFilterModel> filters) {
        this.filters = filters;
    }

    public Integer getOffset() {
        return offset;
    }

    public void setOffset(Integer offset) {
        this.offset = offset;
    }

    public Integer getFetch_max_count() {
        if (fetch_max_count == null || fetch_max_count == 0) {
            return 10;
        }
        return fetch_max_count;
    }

    public void setFetch_max_count(Integer fetch_max_count) {
        this.fetch_max_count = fetch_max_count;
    }

    public List<EtlTransformRuleModel> getTransformRules() {
        return transformRules;
    }

    public void setTransformRules(List<EtlTransformRuleModel> transformRules) {
        this.transformRules = transformRules;
    }

    public Map<Long, List<EtlTransformRuleModel>> getCheckRuleMap() {
        return checkRuleMap;
    }

    public void setCheckRuleMap(Map<Long, List<EtlTransformRuleModel>> checkRuleMap) {
        this.checkRuleMap = checkRuleMap;
    }

    public Map<Long, List<EtlTransformRuleModel>> getConvertRuleMap() {
        return convertRuleMap;
    }

    public void setConvertRuleMap(Map<Long, List<EtlTransformRuleModel>> convertRuleMap) {
        this.convertRuleMap = convertRuleMap;
    }

    public Map<Long, EtlTransformRuleTypeModel> getRuleTypeMap() {
        return ruleTypeMap;
    }

    public void setRuleTypeMap(Map<Long, EtlTransformRuleTypeModel> ruleTypeMap) {
        this.ruleTypeMap = ruleTypeMap;
    }

    public List<EtlTableRelRuleModel> getTableRelRules() {
        return tableRelRules;
    }

    public void setTableRelRules(List<EtlTableRelRuleModel> tableRelRules) {
        this.tableRelRules = tableRelRules;
    }

    public Map<Long, List<EtlTableRelRuleModel>> getMasterTableRelRuleMap() {
        return masterTableRelRuleMap;
    }

    public void setMasterTableRelRuleMap(Map<Long, List<EtlTableRelRuleModel>> masterTableRelRuleMap) {
        this.masterTableRelRuleMap = masterTableRelRuleMap;
    }

    public Map<Long, List<EtlTableRelRuleModel>> getSlaveTableRelRuleMap() {
        return slaveTableRelRuleMap;
    }

    public void setSlaveTableRelRuleMap(Map<Long, List<EtlTableRelRuleModel>> slaveTableRelRuleMap) {
        this.slaveTableRelRuleMap = slaveTableRelRuleMap;
    }
}
